package com.ljx.qqpro.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.ljx.qqpro.common.exception.MyException;
import com.ljx.qqpro.common.utils.UserHolder;
import com.ljx.qqpro.dto.apply.ApplyDto;
import com.ljx.qqpro.dto.apply.ApplyMessage;
import com.ljx.qqpro.dto.chat.ChatApply;
import com.ljx.qqpro.dto.user.UserApply;
import com.ljx.qqpro.entity.*;
import com.ljx.qqpro.service.*;
import com.ljx.qqpro.vo.apply.ApplySave;
import com.ljx.qqpro.websocket.ApplyWebsocket;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljx.qqpro.common.utils.PageUtil;
import com.ljx.qqpro.common.utils.Query;

import com.ljx.qqpro.dao.ApplyDao;
import org.springframework.transaction.annotation.Transactional;


@Service("applyService")
public class ApplyServiceImpl extends ServiceImpl<ApplyDao, ApplyEntity> implements ApplyService {

    @Autowired
    private ApplyWebsocket applyWebsocket;

    @Autowired
    private UserCountService userCountService;

    @Autowired
    private ChatUserService chatUserService;

    @Autowired
    private UserService userService;

    @Override
    public PageUtil queryPage(Map<String, Object> params) {
        IPage<ApplyEntity> page = this.page(
                new Query<ApplyEntity>().getPage(params),
                new QueryWrapper<ApplyEntity>()
        );

        return new PageUtil(page);
    }

    @Transactional
    @Override
    public void saveApply(ApplySave applySave) {
        Long userId = UserHolder.getUser().getId();

        // 若是检查是否已经添加了该群或者该用户
        ChatUserEntity chatUser = chatUserService.getOne(new QueryWrapper<ChatUserEntity>().eq("user_id", userId).eq("status", 1)
                .eq("chat_id", applySave.getTargetId()));
        if(chatUser != null){
            if(applySave.getType() == 1) throw new MyException("该用户已经是您的好友");
            else throw new MyException("您已经是该群的成员");
        }

        // 检查是否已经申请
        ApplyEntity queryApply = this.baseMapper.selectOne(new QueryWrapper<ApplyEntity>().eq("creater_id", userId)
                .eq("target_id", applySave.getTargetId()).eq("type", applySave.getType()));
        if(queryApply != null){
            throw new MyException("请勿重复申请");
        }

        ApplyEntity applyEntity = BeanUtil.copyProperties(applySave, ApplyEntity.class);
        applyEntity.setCreaterId(userId);
        this.baseMapper.insert(applyEntity);

        // 调用websocket
        UserEntity userEntity = UserHolder.getUser();

        // 查询用户新申请的数量
        UserCountEntity userCountEntity = userCountService.getOne(new QueryWrapper<UserCountEntity>().eq("status", 1).eq("id", userId));
        if (userCountEntity == null){
            // 不存在就创建一个
            userCountEntity = new UserCountEntity();
            userCountEntity.setId(userEntity.getId());
            userCountEntity.setNewApplyCount(0);
            userCountService.save(userCountEntity);
        }

        userCountEntity.setNewApplyCount(userCountEntity.getNewApplyCount() + 1);

        ApplyMessage applyMessage = new ApplyMessage();
        applyMessage.setUserId(userEntity.getId());
        applyMessage.setCount(userCountEntity.getNewApplyCount());
        applyMessage.setType(applySave.getType());

        List<Long> targetIdList = new ArrayList<>();
        // 判断是群聊还是单聊，来获取目标对象ID
        if(applySave.getType() == 1){
            targetIdList.add(applySave.getTargetId());
            applyMessage.setTargetIdList(targetIdList);
        }
        else{
            // 查询群聊管理员
            List<ChatUserEntity> list = chatUserService.list(new QueryWrapper<ChatUserEntity>().eq("chat_id", applySave.getTargetId()).eq("status", 1)
                    .eq("is_admin", 1));

            List<Long> collect = list.stream().map(item -> {
                return item.getUserId();
            }).collect(Collectors.toList());

            applyMessage.setTargetIdList(collect);
        }

        applyWebsocket.onMessage(JSONUtil.toJsonStr(applyMessage));

        // 更新新申请数量
        userCountService.updateById(userCountEntity);
    }

    @Override
    public ApplyDto getUserApply(Long userId) {

        ApplyDto applyDto = new ApplyDto();

        // 获取用户的申请的好友和被申请
        List<UserApply> userApplies = this.baseMapper.queryUserApply(userId);

        List<ChatApply> chatApplies = new ArrayList<>();

        // 获取用户申请的群聊
        chatApplies.addAll(this.baseMapper.queryChatApply(userId));

        // 获取用户管理的群聊
        List<ChatUserEntity> userAdminChatList = chatUserService.list(new QueryWrapper<ChatUserEntity>().eq("user_id", userId).eq("is_admin", 1));
        for (ChatUserEntity chatUserEntity : userAdminChatList) {
            Long chatId = chatUserEntity.getChatId();

            // 查询群聊的申请记录
            List<ApplyEntity> applyEntities = this.baseMapper.selectList(new QueryWrapper<ApplyEntity>().eq("status", 1).eq("type", 2)
                    .eq("target_id", chatId).orderByDesc("create_time"));

            // 获取每个申请者的信息
            for (ApplyEntity applyEntity : applyEntities) {
                UserEntity one = userService.getOne(new QueryWrapper<UserEntity>().eq("id", applyEntity.getCreaterId()).eq("status", 1));

                ChatApply chatApply = new ChatApply();
                BeanUtils.copyProperties(one, chatApply);
                BeanUtils.copyProperties(applyEntity, chatApply);

                chatApplies.add(chatApply);
            }
        }

        applyDto.setChatApplyList(chatApplies);
        applyDto.setUserApplyList(userApplies);

        return applyDto;
    }
}